package be.rivendale.geometry;

import be.rivendale.mathematics.*;
import org.junit.Assert;
import org.junit.Test;

import java.util.List;

public class RawFileLoaderTest {
    private static final Point DEFAULT_RELATIVE_POSITION = new Triple(0, 0, 0);

    @Test(expected = IllegalArgumentException.class)
	public void constructorFromFileRequiresFileNameToBeNotNull() {
        RawFileLoader.loadRawFile(null, DEFAULT_RELATIVE_POSITION);
	}

	@Test(expected = IllegalArgumentException.class)
	public void constructorFromFileRequiresFileToExist() {
		RawFileLoader.loadRawFile("unexistingFile.raw", DEFAULT_RELATIVE_POSITION);
	}

	@Test(expected = UnsupportedOperationException.class)
	public void rawFileContainingQuadsThrowsAnUnsupportedOperationException() {
	    RawFileLoader.loadRawFile("./test-data/quadContainingRawFile.txt", DEFAULT_RELATIVE_POSITION);
	}

	@Test(expected = IllegalArgumentException.class)
	public void invalidRawFileWithLessThenNineWordsOnTheFirstLineThrowsAnIllegalArgumentException() {
	    RawFileLoader.loadRawFile("./test-data/invalidRawFile.txt", DEFAULT_RELATIVE_POSITION);
	}

	@Test(expected = IllegalArgumentException.class)
	public void invalidRawFileSpeciallyBuiltToFoolFileValidationThrowsAnIllegalArgumentException() {
	    RawFileLoader.loadRawFile("./test-data/invalidRawFileToFoolFileValidation.txt", DEFAULT_RELATIVE_POSITION);
	}

	@Test
	public void validRawFileInitializesModelCorrectly() {
		TriangleModel model = RawFileLoader.loadRawFile("./test-data/validRawFile.txt", DEFAULT_RELATIVE_POSITION);
        List<Triangle> triangles = model.getTriangles();
        Assert.assertEquals(2, triangles.size());
		MathematicalAssert.assertTriangleEquals(new Triangle(
                new Vertex(1.414214, -0.707106, 0.707107),
                new Vertex(1.414214, 0.707107, -0.707107),
                new Vertex(0, 1.707107, 0.292893)
        ), triangles.get(0));
		MathematicalAssert.assertTriangleEquals(new Triangle(
			new Vertex(0, 0.292893,  1.707107),
			new Vertex(1.414214, -0.707106,  0.707107),
			new Vertex(0, 1.707107, 0.292893)
		), triangles.get(1));
	}

    @Test
	public void modelIsCreatedRelativeToRelativePosition() {
        Triple relativePosition = new Triple(1, -2, 3);
        TriangleModel model = RawFileLoader.loadRawFile("./test-data/validRawFile.txt", relativePosition);
        List<Triangle> triangles = model.getTriangles();
        Assert.assertEquals(2, triangles.size());
		MathematicalAssert.assertTriangleEquals(new Triangle(
                new Vertex(1.414214 + relativePosition.getX(), -0.707106 + relativePosition.getY(), 0.707107 + relativePosition.getZ()),
                new Vertex(1.414214 + relativePosition.getX(), 0.707107 + relativePosition.getY(), -0.707107 + relativePosition.getZ()),
                new Vertex(0 + relativePosition.getX(), 1.707107 + relativePosition.getY(), 0.292893 + relativePosition.getZ())
        ), triangles.get(0));
		MathematicalAssert.assertTriangleEquals(new Triangle(
			new Vertex(0 + relativePosition.getX(), 0.292893 + relativePosition.getY(),  1.707107 + relativePosition.getZ()),
			new Vertex(1.414214 + relativePosition.getX(), -0.707106 + relativePosition.getY(),  0.707107 + relativePosition.getZ()),
			new Vertex(0 + relativePosition.getX(), 1.707107 + relativePosition.getY(), 0.292893 + relativePosition.getZ())
		), triangles.get(1));
    }

    @Test(expected = IllegalArgumentException.class)
	public void relativePositionMostNotBeNull() {
        RawFileLoader.loadRawFile("./test-data/validRawFile.txt", null);
    }
}
